package admin

import (
	"gq_volunteer_platform/bean"
	"gq_volunteer_platform/model/admin"
	"gq_volunteer_platform/model/weixin"
	"strings"

	"github.com/dchest/captcha"
	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

func CaptchaId(c *gin.Context) {

	var captchaId = captcha.NewLen(4)

	c.String(200, captchaId)
}

func Captcha(c *gin.Context) {

	var captchaId = c.Query("captchaId")

	c.Header("captchaid", captchaId)

	if err := captcha.WriteImage(c.Writer, captchaId, 100, 50); err != nil {
		bean.Log.Warning(err)
		c.String(400, "验证码生成失败")
		return
	}
}

func Login(c *gin.Context) {

	var req struct {
		Mobile    string `binding:"max=255"`
		Password  string `binding:"max=255"`
		CaptchaId string `binding:"max=255"`
		Digits    string `binding:"max=255"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		bean.Log.Warning(err)
		c.String(400, err.Error())
		return
	}

	// 请求记录
	var rec admin.AdminRecord
	rec.Method = c.Request.Method
	rec.ApiPath = c.FullPath()
	rec.Ip = c.ClientIP()
	rec.AdminName = "尝试登录账号：" + req.Mobile
	if err := bean.MysqlDb.Save(&rec).Error; err != nil {
		bean.Log.Error(err)
		return
	}

	// 验证码判断
	if !captcha.VerifyString(req.CaptchaId, req.Digits) {
		bean.Log.Info("验证码错误:" + req.Digits)
		c.String(400, "验证码错误")
		return
	}

	// 密码加密
	if s, err := admin.Md5(req.Password); err != nil {
		bean.Log.Error(err)
		c.String(500, "内部错误m")
		return
	} else {
		req.Password = s
	}

	// 对比查找用户
	var one admin.Admin

	if err := bean.MysqlDb.Where("`mobile`=? and `password`=?", req.Mobile, req.Password).First(&one).Error; err != nil {
		bean.Log.Error(err)
		c.String(400, "账号或密码错误")
		return
	}

	c.PureJSON(200, one)

	// 更新请求记录
	rec.AdminName = one.Name
	rec.AdminID = one.ID

	if err := bean.MysqlDb.Save(&rec).Error; err != nil {
		bean.Log.Error(err)
		return
	}

	// 放入admin 信息，record 中间件使用
	c.Set("admin", one)
}

func Logout(c *gin.Context) {
	// 获取登录用户对象
	var one admin.Admin
	if err := one.Get(c); err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}
	//

	if err := one.NewToken(); err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	var two admin.Admin
	two.ID = one.ID
	two.Token = one.Token

	if err := bean.MysqlDb.Updates(&two).Error; err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	c.String(200, "ok")
}

// UUID生成新的ticket
func LoginQrCodeTicket(c *gin.Context) {

	var ticket = uuid.New().String()
	ticket = strings.ReplaceAll(ticket, "-", "")

	c.String(200, ticket)
}

// 登录二维码（微信小程序）
func LoginQrCode(c *gin.Context) {

	var req struct {
		Ticket     string `binding:"alphanum,len=32"`
		EnvVersion string `binding:"oneof=release trial develop"`
		Page       string `binding:"max=255"`
		Width      uint   `binding:"min=280,max=1280"`
	}

	if err := c.ShouldBindQuery(&req); err != nil {
		bean.Log.Warning(err)
		c.String(400, err.Error())
		return
	}

	// 检查ticket是否已经存在
	var ex admin.AdminQrTicket
	if err := bean.MysqlDb.Where("`ticket`=?", req.Ticket).Find(&ex).Error; err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	if ex.ID != 0 {
		c.String(400, "该二维码已存在，请重新生成")
		return
	}

	// 生成ticket数据
	var one admin.AdminQrTicket
	var ticket, err = one.New(req.Ticket)
	if err != nil {
		bean.Log.Error(err)
		c.String(500, err.Error())
		return
	}

	var qr weixin.QRCodeGetReq
	qr.Scene = ticket
	qr.EnvVersion = req.EnvVersion
	qr.IsHyaline = false
	qr.Page = req.Page
	qr.Width = req.Width
	qr.CheckPath = false

	by, err := qr.QRCodeGet()
	if err != nil {
		c.String(500, err.Error())
		bean.Log.Warning(err.Error())
		return
	}

	c.Header("Content-Type", "image/jpeg")
	c.Header("Content-Disposition", "attachment; filename=\"bind_qr_code.jpeg\"")

	c.Writer.Write(by)
}

// 检查是否授权二维码登录（微信小程序）
// 需要定时扫描
func CheckQrCodeLogin(c *gin.Context) {

	var req struct {
		Ticket string `binding:"alphanum,len=32"`
	}

	if err := c.ShouldBindQuery(&req); err != nil {
		bean.Log.Warning(err)
		c.String(400, err.Error())
		return
	}

	// 获取登录用户对象
	var one admin.AdminQrTicket
	if err := bean.MysqlDb.Where("`ticket`=?", req.Ticket).First(&one).Error; err != nil {
		bean.Log.Error(err)
		c.PureJSON(200, gin.H{
			"code": "二维码已过期",
		})
		return
	}

	// 用户取消授权
	if one.Confirmed == "拒绝" {
		c.PureJSON(200, gin.H{
			"code": "用户取消授权",
		})
		return
	}

	// 用户未授权
	if one.Confirmed == "" {
		c.PureJSON(200, gin.H{
			"code": "用户未授权",
		})
		return
	}

	var two admin.Admin
	if err := bean.MysqlDb.Where("`id`=?", one.AdminId).First(&two).Error; err != nil {
		bean.Log.Error(err)
		c.String(500, "没有该用户")
		return
	}

	c.PureJSON(200, gin.H{
		"code":  "用户已授权",
		"admin": two,
	})
}
